import 'package:fluttertoast/fluttertoast.dart';
import 'package:freemusic/model/AbstractSong.dart';
import 'package:freemusic/model/Gedan.dart';
import 'package:freemusic/model/KugouSong.dart';
import 'package:freemusic/model/LocalSong.dart';
import 'package:freemusic/model/NeteaseSong.dart';
import 'package:freemusic/model/QQSong.dart';
import 'package:freemusic/model/netease/NeteaseAccount.dart';
import 'package:freemusic/model/netease/NeteaseDiss.dart';
import 'package:freemusic/model/qq/QQDiss.dart';
import 'package:freemusic/services/AbstractServices.dart';
import 'package:freemusic/services/SongServices.dart';
import 'package:freemusic/stores/CloudDissStores.dart' as cloudDissStores;
import 'package:freemusic/stores/GedanStores.dart' as gedanStores;
import 'package:freemusic/utils/SQFLite.dart';
import 'package:freemusic/stores/PlayerStores.dart' as playerStores;
import 'package:freemusic/utils/request/Request.dart' as request;
import 'package:freemusic/utils/request/netease.dart';
import 'package:freemusic/utils/request/qq.dart';
import 'package:freemusic/model/qq/QQAccount.dart';

class GedanServices extends AbstractServices {
  static GedanServices _instance;
  static SQFLiteUtil _sqfLiteUtil;

  GedanServices._();

  static GedanServices getInstace() {
    if (_instance == null) {
      _instance = GedanServices._();
    }
    if (_sqfLiteUtil == null) {
      _instance._init();
    }
    return _instance;
  }

  void _init() {
    SQFLiteUtil.getInstance().then((v) {
      _sqfLiteUtil = v;
    });
  }

  Future<bool> addNewGedan(String name) async {
    if (name == null) {
      return false;
    }
    if (name.trim().isEmpty) {
      return false;
    }
    DateTime dateTime = DateTime.now();

    _sqfLiteUtil.open().transaction((txn) async {
      List<Map<String, dynamic>> result = await txn
          .rawQuery("SELECT COUNT(id) FROM `gedan` WHERE `gd_name` = '$name'");
      Map<String, dynamic> current = result[0];
      if (current['COUNT(id)'] > 0) {
        Fluttertoast.showToast(msg: "歌单已存在", gravity: ToastGravity.CENTER);
        return;
      }

      txn
          .rawInsert(
              "INSERT INTO `gedan` (`gd_name`, `created`) VALUES ('$name', '$dateTime')")
          .then((id) {
        Gedan gedan = Gedan();
        gedan.id = id;
        gedan.gdName = name;
        gedan.count = 0;
        gedanStores.appendGedanList(gedan);
      });
    });
    return true;
  }

  void loadGedanList() {
    SQFLiteUtil.getInstance().then((sql) {
      //
      sql
          .open()
          .rawQuery(
              "SELECT t.*, (SELECT COUNT(v.id) FROM `gedan_song` v WHERE v.gd_id = t.id ) as `count` FROM `gedan` t ORDER BY t.id")
          .then((list) {
        List<Gedan> gedanList = List();
        list.forEach((item) {
          Gedan info = Gedan();
          info.fromDataBase(item);
          gedanList.add(info);
        });
        gedanStores.changeGedanList(gedanList);
      });
    });
  }

  Future<bool> deleteGedan(Gedan gedan) async {
    await _sqfLiteUtil
        .open()
        .rawDelete("DELETE FROM `gedan` WHERE `id` = ${gedan.id}");

    await _sqfLiteUtil
        .open()
        .rawDelete("DELETE FROM `gedan_song` WHERE `gd_id` = ${gedan.id}");
    gedanStores.deleteGedanSongByName(gedan);
    return true;
  }

  Future<Gedan> queryGedanByName(String name) async {
    List<Map<String, dynamic>> result = await _sqfLiteUtil
        .open()
        .rawQuery("SELECT * FROM `gedan` WHERE `gd_name` = '$name'");
    Gedan gedan = Gedan();
    result.forEach((item) {
      gedan.fromDataBase(item);
    });
    queryGedanSongs(gedan.id);
    return gedan;
  }

  void queryGedanSongs(int gedanId) async {
    List<Map<String, dynamic>> allSongs = await _sqfLiteUtil.open().rawQuery(
        "SELECT s.* FROM `song` s , `gedan_song` g WHERE s.hash = g.song_hash AND g.gd_id = $gedanId ");
    List<AbstractSong> songinfos = List();
    allSongs.forEach((Map<String, dynamic> item) {
      String platform = item['platform'];
      AbstractSong info;
      switch (platform) {
        case "kugou":
          info = KugouSong();
          break;
        case "qq":
          info = QQSong();
          break;
        case "netease":
          info = NeteaseSong();
          break;
        case "local":
          info = LocalSong();
          break;
      }
      info.fromDataBase(item);
      songinfos.add(info);
    });
    gedanStores.changeGedanSongs(songinfos);
  }

  Future<bool> addSongToGedan(Gedan gedan, AbstractSong song) async {
    //先查询该歌曲是否已经保存到该歌单中，
    List<Map<String, dynamic>> result = await _sqfLiteUtil.open().rawQuery(
        "SELECT COUNT(id) FROM gedan_song WHERE gd_id = ${gedan.id} AND song_hash = '${song.hash}'");
    Map<String, dynamic> current = result[0];
    if (current['COUNT(id)'] > 0) {
      Fluttertoast.showToast(msg: "当前歌单已添加，试试其他歌单");
      return false;
    }

    song = await request.getSong(song);

    await _sqfLiteUtil.open().transaction((txn) async {
      //查询song表中是否已有该歌曲
      List<Map<String, dynamic>> result = await txn.rawQuery(
          "SELECT COUNT(id) FROM `song` WHERE `hash` = '${song.hash}'");
      Map<String, dynamic> current = result[0];
      if (current['COUNT(id)'] == 0) {
        txn.insert("song", song.toMap());
      }
      txn.rawInsert("""
        INSERT INTO `gedan_song` (`gd_id`, `song_hash`) VALUES (${gedan.id}, '${song.hash}')
      """);
      return;
    });
    gedan.count = gedan.count + 1;
    return true;
  }

  //从歌单中删除音乐
  Future<bool> deleteSongFromGedan(int gedanId, String hash) async {
    await _sqfLiteUtil.open().transaction((txn) async {
      int count = await txn.rawDelete(
          "DELETE FROM `gedan_song` WHERE gd_id = $gedanId AND song_hash = '$hash'");
      return;
    });
    queryGedanSongs(gedanId);
    gedanStores.subGedanCount(gedanId);
    return true;
  }

  //播放本地歌单中的所有歌曲
  void playGedanAllSong(int gedanId, List<AbstractSong> songs) {
    playerStores.changeSongSheet(songs);
    SongServices.getInstace().changeTempSongList(songs);
  }

  void getNeteaseDiss(String account, String password) async {
    NeteaseAccount netease =
        await request.getAccount(account, password, "netease");
    if (netease.id == null) {
      Fluttertoast.showToast(msg: "账号或者密码不对");
      return;
    }
    netease.account = account;
    netease.password = password;
    cloudDissStores.changeNeteaseAccount(netease);
    List<NeteaseDiss> disses = await NeteaseAPI.getSongSheet(netease.id);
    cloudDissStores.changeNeteaseDisses(disses);
  }

  //获取qq号下的歌单
  void getQQSongSheet(String cookie) async {
    // List<QQDiss> reslut = await request.getSongDiss(cookie, "qq");
    Map json = await QQAPI.getSongSheet(cookie);
    QQDiss diss = QQDiss();

    if (json['code'] != 0) {
      Fluttertoast.showToast(msg: "歌单获取失败");
      return;
    }
    QQAccount account = QQAccount();
    account.fromRemoteJosn(json['data']['creator']);
    cloudDissStores.changeQQAccount(account);
    cloudDissStores.changeQQDisses(diss.fromRemoteJson(json));
  }

  //获取歌单下的歌曲
  void getQQDissSongs(String qq, int dissId) async {
    request.getDissSongs("qq", qq, dissId).then((json) {
      if (json['code'] != 0) {
        return;
      }
      Map cdMap = json['cdlist'][0];
      QQDiss diss = QQDiss();
      diss.title = cdMap['dissname'];
      diss.picurl = cdMap['logo'];
      diss.subtitle = cdMap['desc'];

      cloudDissStores.changeDiss(diss);

      List songlist = cdMap['songlist'];
      List<QQSong> qqSongs = List();
      songlist.forEach((item) {
        QQSong info = QQSong();
        Map singer = item['singer'][0];
        info.hash = item['songmid'];
        info.songName = item['songname'];
        info.singerName = singer['name'];
        info.albumid = item['albumid'];
        info.songid = item['songid'];
        info.albummid = item["albummid"];
        info.albumname = item["albumname"];
        info.size128 = item['size128'];
        info.size320 = item['size320'];
        info.sizeflac = item['sizeflac'];
        info.sizeogg = item['sizeogg'];
        info.type = "mp3";
        info.platform = "qq";
        info.timeLength = Duration(seconds: item['interval']);
        qqSongs.add(info);
      });
      cloudDissStores.changeDissSongs(qqSongs);
    });
  }

  void getNeteaseDissSongs(int dissId) async {
    NeteaseAPI.getDissSongs(dissId).then((Map result) {
      if (result['code'] != 200) {
        Fluttertoast.showToast(
          msg: "获取歌曲失败",
        );
        return;
      }

      NeteaseDiss diss = NeteaseDiss();
      Map playlist = result['playlist'];
      diss.name = playlist['name'];
      diss.coverImgUrl = playlist['coverImgUrl'];
      diss.description = playlist['description'] == null? "": playlist['description'];
      diss.id = playlist['id'];
      diss.playCount = playlist['playCount'];
      diss.trackCount = playlist['trackCount'];

      cloudDissStores.changeDiss(diss);

      List<NeteaseSong> songs = List();
      List tracks = playlist['tracks'];
      tracks.forEach((track) {
        NeteaseSong song = NeteaseSong();

        song.hash = "netease_${track['id']}";
        song.songName = track['name'];
        List ar = track['ar'];
        String singerName = "";
        int arLength = ar.length;
        if(arLength >0){
          singerName = ar[0]['name'];
        }
        if(arLength > 1){
          for(int i = 1; i< arLength; i++){
            singerName += ", ${ar[i]['name']}";
          }
        }
        song.singerName = singerName;
        song.timeLength = Duration(milliseconds: track['dt']);
        song.platform = SongPlatform.netease;
        song.type = "mp3";

        Map al = track['al'];
        song.img = al['picUrl'];

        songs.add(song);
      });
      cloudDissStores.changeDissSongs(songs);
    });
  }
}
